package ru.spb.nicetu.schoolproject.data;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

import javax.swing.*;
import java.util.List;

/**
 * Created by dchernyshov on 05.04.15.
 */
public class HibernatePagination<T> {
    private int pageSize;
    private int firstResult;
    private Long maxCount;

    private Session session;

    private Class<T> clazz;

    private List<T> page;

    public HibernatePagination (Class<T> clazz, int pageSize) {
        this.clazz = clazz;
        this.pageSize = pageSize;
        firstResult = 0;
        updateCount();
        page = getPage(0);
    }

    public boolean removeObject(T object) {
        session = HibernateUtil.getInstance().getSession();
        try {
            session.beginTransaction();
            session.delete(object);
            session.getTransaction().commit();
            return true;
        }
        catch (HibernateException e) {
            JOptionPane.showMessageDialog(null,
                    "Ошибка удаления - возможно, объект связан с дургим объектом");
            session.getTransaction().rollback();
            return false;
        }
        finally {
            HibernateUtil.closeSession();
        }
    }

    public T getValue(String uniqueField, int value) {
        session = HibernateUtil.getInstance().getSession();
        Criteria criteria = session.createCriteria(clazz);
        criteria.add(Restrictions.eq(uniqueField, value));
        return (T)criteria.list().get(0);
    }

    public List<T> getPage(int firstRes) {
        session = HibernateUtil.getInstance().getSession();
        Criteria criteria = session.createCriteria(clazz);
        criteria.setFirstResult(firstRes);
        criteria.setMaxResults(pageSize);
        return (List<T>) criteria.list();
    }

    public List<T> updatePage() {
        updateCount();
        return  getPage(firstResult);
    }

    public void updateCount() {
        session = HibernateUtil.getInstance().getSession();
        Criteria criteriaCount = session.createCriteria(clazz);
        criteriaCount.setProjection(Projections.rowCount());
        maxCount = (Long) criteriaCount.uniqueResult();
    }

    public List<T> getNextPage() {
        if (hasNextPage()) {
            firstResult += pageSize;
            page = getPage(firstResult);
        }
        return page;
    }

    public List<T> getPreviousPage() {
        if (hasPreviousPage()) {
            firstResult -= pageSize;
            page = getPage(firstResult);
        }
        return page;
    }

    public boolean hasNextPage() {
        if (firstResult + pageSize < maxCount) {
            return true;
        }
        else {
            return false;
        }
    }

    public boolean hasPreviousPage() {
        if (firstResult - pageSize >= 0) {
            return true;
        }
        else {
            return false;
        }
    }

    public int getPageSize() {
        return pageSize;
    }

    public int getFirstResult() {
        return firstResult;
    }

    public Long getMaxCount() {
        return maxCount;
    }
}
